<template>
	<a-modal centered :width="690" v-model:visible="visible" bodyStyle="padding:0" :footer="null" ref="modalRef" :wrap-style="{ overflow: 'hidden' }">
		<div class="modal">
			<div class="bmain">
				<div class="mbody mixedBody">
					<div class="tag" v-if="!options">
						<span v-for="item in tabList" :key="item.type"
							:class="[actIndex === item.type ? 'active' : '']"
							@click="SwitchTab(item.type)">{{ item.label }}</span>
					</div>
					<div class="search mixedSearch">
						<a-input v-model:value="searchText" @keyup.enter.stop="fuzzySearch(searchText)" v-bind="attrs" :style="{height:'32px',lineHeight:'32px'}"></a-input>
						<a-button :style="{ background: '#3f7fbf', margin: '0 5px', border: '0', color: '#fff' }"
							type="primary" @click="fuzzySearch(searchText)">搜索</a-button>
						<a-button :style="{ background: '#3f7fbf', border: '0', color: '#fff' }" type="primary"
							@click="resetSearch('')">重置</a-button>
					</div>
					<div class="transfer">
						<!-- 选择人员 -->
						<div class="tranleft" v-if="actIndex === 'emp'">
							<div class="desc">待选人员（您可以通过搜索查询人员）</div>
							<div class="listsmix">
								<div
									v-for="(item, index) in leftList"
									:key="item.id"
									:class="{ 'act': item.selected }"
									@click="selectListItemfn(item, $event, leftList)"
									@dblclick="toRight"
									@mousedown="startSelectionfn($event, index, leftList)"
									@mouseover="continueSelectionfn($event, index, leftList)"
									@mouseup="endSelectionfn($event)"
									class="listItem">
									<div class="listItemTxt">{{ item.displayName }}</div>
								</div>
							</div>
						</div>
						<div class="tranmid" v-if="actIndex === 'emp'">
							<div class="listmix">
								<p v-for="(item, index) in sortNum" :key="index" @click="selectLetters(index, item)" :class="[ index === currentIndex ? 'selected' : '' ]">{{ item }}</p>
							</div>
						</div>
						<!-- 选择群组 -->
						<div class="tranleft" v-if="actIndex === 'group'">
							<div class="desc">待选群组（您可以通过搜索查询群组）</div>
							<div class="listsmix borderRight">
								<div
									v-for="(item, index) in leftList"
									:key="item.id"
									:class="{ 'act': item.selected }"
									@click="selectListItemfn(item, $event, leftList)"
									@dblclick="toRight"
									@mousedown="startSelectionfn($event, index, leftList)"
									@mouseover="continueSelectionfn($event, index, leftList)"
									@mouseup="endSelectionfn($event)"
									class="listItem">
									<div class="listItemTxt">{{ item.displayName }}</div>
								</div>
							</div>
						</div>
						<!-- 选择组织 -->
						<div class="tranleft" v-if="actIndex === 'org'">
							<div class="desc">待选组织（您可以通过搜索查询组织）</div>
							<div class="listsmix borderRight">
								<a-tree
									v-model:value="value"
									style="width: 100%"
									:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
									:multiple="true"
									tree-default-expand-all
									ref="treeref"
									:selectedKeys="hhgSelectedKeys"
									@select="onSelect"
									@dblclick="handleTreeDblClick"
									:tree-data="leftList"
									tree-node-filter-prop="label"
									>
									<template #title="{ value: val, label }">
										<b v-if="val === 'parent 1-1'" style="color: #08c">{{ label }}</b>
										<template v-else>{{ label }}</template>
									</template>
								</a-tree>
							</div>
						</div>

						<div class="traptip">
							<div class="ttimg ttimg1" @click="toRight"></div>
							<div class="ttimg ttimg2" @click="toLeft"></div>
							<div class="ttimg ttimg3" @click="clearRight"></div>
						</div>
						<div class="tranright">
							<div class="desc">已选：</div>
							<div class="listsmix">
								<div class="listItem" v-for="(item, index) in rightList" :key="item.id"
									:class="{ 'act': item.selected }"
									@dblclick="removeSingle(item)"
									@click="selectListItemfn(item, $event, rightList)"
									@mousedown="startSelectionfn($event, index, rightList)"
									@mouseover="continueSelectionfn($event, index, rightList)"
									@mouseup="endSelectionfn($event)">
									<div class="listItemTxt">{{ item.displayName }}</div>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
			<div class="mfoot">
				<a-button :style="{ background: '#3f7fbf', border: '0', color: '#fff' }" type="primary"
					@click="selectedMember">确定</a-button>
				<a-button :style="{ background: '#3f7fbf', border: '0', color: '#fff', margin: '0 12px' }" type="primary"
					@click="clearList">清空</a-button>
				<a-button :style="{ background: '#dddddd', border: '0', color: '#666' }" @click="closeModal">关闭</a-button>
			</div>
		</div>
		<!-- 拖动 -->
		<template #title>
			<div ref="modalTitleRef" style="width: 100%; cursor: move">选择成员</div>
		</template>
		<template #modalRender="{ originVNode }">
			<div :style="transformStyle">
				<component :is="originVNode" />
			</div>
		</template>
	</a-modal>
</template>
<script setup>
import { message } from "ant-design-vue"
import { ref, defineEmits, defineProps, watch, useAttrs, watchEffect, computed, defineExpose } from 'vue'
import { selectListItem, startSelection, endSelection, continueSelection, deepClone, mergeAndSetSelected } from './utils'
//拖动
import { useDraggable } from '@vueuse/core'

//测试数据
const allList = ref()
const leftList = ref()
const rightList = ref([])
const searchText = ref('')
const treeList = ref([])

//父组件传过来的值
const props = defineProps({
	config: {
		type: Object,
		default: () => { }
	},
	list: {
		type: Array,
		default: () => [],
		require: false
	} 
})
watch(() => props.list, (val) => {
  if (val) {
	allList.value = val
	leftList.value = val
  }
}, { immediate: true }, { deep: true })
watch(() => props.config, (val) => {
  if (val.displayList) {
	rightList.value = val.displayList
  }
}, { immediate: true }, { deep: true })
//属性穿透
const attrs = useAttrs()

const visible = ref(false)

//选项卡特效
const tabList = ref([
	{ type: 'emp', label: '选择人员' },
	{ type: 'group', label: '选择群组' },
	{ type: 'org', label: '选择组织' }
])
const emit = defineEmits(['selectedMember', 'fuzzySearch', 'clearMixedMebmer', 'SwitchTab'])

const options = ref(props.config.options)
const actIndex = ref(props.config.options ? props.config.options : 'emp')
const SwitchTab = type => {
	actIndex.value = type
	allList.value = []
	leftList.value = []
	currentIndex.value = 0
	emit('SwitchTab', type)
}

//多选人员设置
const selectListItemfn = (item, event, list)=> {
	return selectListItem(item, event, list)
}
const startSelectionfn = (event, index, list)=> {
	return startSelection(event, index, list)
}
const endSelectionfn = (event)=> {
	return endSelection(event)
}
const continueSelectionfn = (event, index, list)=> {
	return continueSelection(event, index, list)
}
//双击取消选择
const removeSingle = i=> {
	i.selected = true
	const filterList = deepClone(rightList.value.filter(item=> !item.selected))
	rightList.value = filterList
}
const hhgSelectedKeys = ref([])
/*组织选择*/
const onSelect = (selectedKeys, e)=> {
	treeList.value = e.selectedNodes
	hhgSelectedKeys.value = selectedKeys
}
// 双击事件处理
const handleTreeDblClick = (event, e) => {
	
	const item = e?.dataRef
	// 检查 b 数组中是否存在相同 id 的对象
	const existingItem = rightList.value.find(bItem => bItem.id === item.id)
	// 如果不存在相同 id 的对象，则将该对象推送到 b 数组中
	if (!existingItem) {
		rightList.value.push(deepClone({
			pId: item.pId,
			id: item.id,
			displayName: item.name,
			code: item.code,
			label: item.name,
			value: item.id
		}))
		
	}
}
const letters = ref('ALL')
//选择字母
const currentIndex = ref(-1)
const selectLetters = (index, zimu)=> {
	letters.value = zimu
	currentIndex.value = index
	emit('fuzzySearch', actIndex.value, { text: searchText.value, letters: zimu })
}

//搜索
const fuzzySearch = (text) => {
	emit('fuzzySearch', actIndex.value, { text, letters: letters.value })
}
//清空右侧数据
const clearRight = ()=> {
	rightList.value = []
}
const resetSearch = () => {
	currentIndex.value = -1
	searchText.value = ''
	emit('fuzzySearch', actIndex.value, { text: '', letters: 'ALL' })
}
//数据转到右侧
const toRight = () => {
	if (actIndex.value === 'org') {
		
		treeList.value.forEach(item=> {
			// 检查 b 数组中是否存在相同 id 的对象
			const existingItem = rightList.value.find(bItem => bItem.id === item.id)
			// 如果不存在相同 id 的对象，则将该对象推送到 b 数组中
			if (!existingItem) {
				rightList.value.push(deepClone({
					pId: item.pId,
					id: item.id,
					displayName: item.name,
					code: item.code,
					label: item.name,
					value: item.id
				}))
				
			}
		})
	} else {
		
		leftList.value.filter(item => item.selected).forEach(item=> {
			// 检查 b 数组中是否存在相同 id 的对象
			const existingItem = rightList.value.find(bItem => bItem.id === item.id)
			// 如果不存在相同 id 的对象，则将该对象推送到 b 数组中
			if (!existingItem) {
				rightList.value.push(deepClone(item))
				rightList.value.forEach(i=> i.selected = false)
			}
			leftList.value.forEach(i=> i.selected = false)
			
		})
	}
}
const toLeft = () => {
	const filterList = deepClone(rightList.value.filter(item=> !item.selected))
	rightList.value = filterList
}
//选择人员
const selectedMember = () => {
	if (rightList.value.length === 0) {
		message.warning('请选择人员')
		return
	}
	let value = rightList.value
	localStorage.setItem('localMember', JSON.stringify(mergeAndSetSelected(JSON.parse(localStorage.getItem('localMember')), rightList.value.filter(i=> i.type === 'emp'))))
	localStorage.setItem('localGroup', JSON.stringify(mergeAndSetSelected(JSON.parse(localStorage.getItem('localGroup')), rightList.value.filter(i=> i.type === 'group'))))
	emit('selectedMember', {
		name: value.map(i => i.displayName).join(','),
		code: value.map(i => i.id),
		data: value
	})
}
const closeModal = () => {
	visible.value = !visible.value
}
const clearList = () => {
	rightList.value = []
	leftList.value.map(item => {
		item.selected = false
		return item
	})
	emit('clearMixedMebmer')
}
//生成26个大写字母
function generateAlphabet() {
	const alphabet = ['ALL']
	for (let i = 65; i <= 90; i++) {
		alphabet.push(String.fromCharCode(i))
	}
	return alphabet
}
const sortNum = ref(generateAlphabet())

//拖动
const modalTitleRef = ref(null)
const { x, y, isDragging } = useDraggable(modalTitleRef)
const startX = ref(0)
const startY = ref(0)
const startedDrag = ref(false)
const transformX = ref(0)
const transformY = ref(0)
const preTransformX = ref(0)
const preTransformY = ref(0)
const dragRect = ref({
	left: 0,
	right: 0,
	top: 0,
	bottom: 0
})
watch([x, y], () => {
	if (!startedDrag.value) {
		startX.value = x.value
		startY.value = y.value
		const bodyRect = document.body.getBoundingClientRect()
		const titleRect = modalTitleRef.value.getBoundingClientRect()
		dragRect.value.right = bodyRect.width - titleRect.width
		dragRect.value.bottom = bodyRect.height - titleRect.height
		preTransformX.value = transformX.value
		preTransformY.value = transformY.value
	}
	startedDrag.value = true
})
watch(isDragging, () => {
	if (!isDragging) {
		startedDrag.value = false
	}
})
watchEffect(() => {
	if (startedDrag.value) {
		transformX.value =
			preTransformX.value +
			Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) -
			startX.value;
		transformY.value =
			preTransformY.value +
			Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) -
			startY.value
	}
})
const transformStyle = computed(() => {
	return {
		transform: `translate(${transformX.value}px, ${transformY.value}px)`
	}
})
defineExpose({ visible, rightList, actIndex, hhgSelectedKeys, currentIndex })
</script>
<style scoped lang="scss"></style>